﻿#include "renders.h"

RenderManager renders;

Appearance::Appearance()
{
}

Appearance::~Appearance()
{
}

Effect_Appearance::Effect_Appearance()
{
}

Effect_Appearance::~Effect_Appearance()
{
}

Enemy_Appearance::Enemy_Appearance()
{
}

Enemy_Appearance::~Enemy_Appearance()
{
}

Boss_Appearance::Boss_Appearance()
{
}

Boss_Appearance::~Boss_Appearance()
{
}

RenderManager::RenderManager()
{
}

RenderManager::~RenderManager()
{
	for (std::map<std::string, Appearance*>::iterator it = bullet_renders.begin(); it != bullet_renders.end(); it++)
		delete it->second;
	for (std::map<std::string, Enemy_Appearance*>::iterator it = enemy_renders.begin(); it != enemy_renders.end(); it++)
		delete it->second;
}

// Создать все доступные рендереры
// Пули:
//  - Appearance_Simple				- "bullet_"				- круглые пули
//  - Appearance_Bullet_Pike1		- "bullet_pike_"		- заострённые пули
// Пули игрока:
//  Appearance_Player_Bullet1	- "player_bullet1"	- цилиндрическая маленькая пуля Нитори
//  Appearance_Player_Bullet2	- "player_bullet2"	- большая круглая пуля Нитори
// Враги:
//  = Enemy_Appearance_Fairy			- "enemy_fairy1"				- обычные феи
//  = Enemy_Appearance_Fairy			- "enemy_fairy2"				- обычные феи с магическим кругом
// Эффекты:
//  * Appearance_Effect_Magic_Flash				- "magic_flash"		- вспышка
//  * Appearance_Effect_Enemy_Shot1				- "enemy_shot100"	- выстрел
//  * Appearance_Effect_Enemy_Shot2				- "enemy_shot_other100"	- выстрел
//  * Appearance_Effect_Score_Float					- "score_float" - всплывающие цифры очков
//  * Appearance_Effect_Player_Bullet_Hit1		- "player_bullet_hit1" - уничтоженная пуля игрока 1
//  * Appearance_Effect_Player_Bullet_Hit2		- "player_bullet_hit2" - уничтоженная пуля игрока 2
//  * Appearance_Effect_Player_Bullet_Hit3		- "player_bullet_hit3" - уничтоженная пуля игрока 3 - пуля 1 в фокус-режиме
//  * Appearance_Effect_Enemy_Bullet_Hit1		- "enemy_bullet_hit1" - эффект лопающейся пули кольцом
//  * Appearance_Effect_Cancelled_Bullet			- "cancelled_bullet" - унчичтоженная пуля противника
//  * Appearance_Effect_Happa_Particle			- "particle_happa" - частичка лист
//  * Appearance_Effect_Small_Particle				- "particle_small" - маленькая точка света
//  * Appearance_Effect_Graze_Particle				- "graze_particle" - частица, отлетающая при грейзе
void RenderManager::Init(CL_GraphicContext &gc, CL_ResourceManager &resources)
{
	bullet_renders["bullet0"] = new Appearance_Simple("bullets", 32);
	bullet_renders["bullet1"] = new Appearance_Simple("bullets", 48);
	bullet_renders["bullet2"] = new Appearance_Simple("bullets", 176);
	bullet_renders["bullet3"] = new Appearance_Simple("bullets", 192);
	bullet_renders["bullet4"] = new Appearance_Simple("bullets", 208);
	bullet_renders["bullet5"] = new Appearance_Simple("bullets", 224);
	bullet_renders["bullet6"] = new Appearance_Simple("bullets", 240);
	bullet_renders["bullet_zoom0"] = new Appearance_Simple_Zoomed("bullets", 32, 2.0f);
	bullet_renders["bullet_zoom1"] = new Appearance_Simple_Zoomed("bullets", 48, 2.0f);
	bullet_renders["bullet_pike1"] = new Appearance_Bullet_Pike("bullets", 16);
	bullet_renders["bullet_pike2"] = new Appearance_Bullet_Pike("bullets", 64);
	bullet_renders["bullet_pike3"] = new Appearance_Bullet_Pike("bullets", 80);
	bullet_renders["bullet_pike4"] = new Appearance_Bullet_Pike("bullets", 96);
	bullet_renders["bullet_pike5"] = new Appearance_Bullet_Pike("bullets", 112);
	bullet_renders["bullet_pike6"] = new Appearance_Bullet_Pike("bullets", 128);
	bullet_renders["bullet_pike7"] = new Appearance_Bullet_Pike("bullets", 144);
	bullet_renders["bullet_pike8"] = new Appearance_Bullet_Pike("bullets", 160);
	bullet_renders["bullet_big0"] = new Appearance_Simple("bullets2", 0);
	bullet_renders["bullet_big1"] = new Appearance_Simple("bullets2", 8);
	bullet_renders["bullet_big2"] = new Appearance_Simple("bullets2", 16);
	bullet_renders["bullet_big3"] = new Appearance_Simple("bullets2", 24);

	bullet_renders["bullet_lazor1"] = new Appearance_Lazor();

	bullet_renders["player_bullet1"] = new Appearance_Player_Bullet1();
	bullet_renders["player_bullet2"] = new Appearance_Player_Bullet2();
	bullet_renders["player_bullet_focus1"] = new Appearance_Player_Bullet_Focus1(1.0f);
	bullet_renders["player_bullet_focus2"] = new Appearance_Player_Bullet_Focus1(1.1f);
	bullet_renders["player_bullet_focus3"] = new Appearance_Player_Bullet_Focus1(1.2f);
	bullet_renders["player_bullet_focus4"] = new Appearance_Player_Bullet_Focus1(1.3f);
	bullet_renders["player_bullet_focus5"] = new Appearance_Player_Bullet_Focus1(1.5f);

	enemy_renders["enemy_fairy1"] = new Enemy_Appearance_Fairy(0, 0, "enemy_fairy1");
	enemy_renders["enemy_fairy2"] = new Enemy_Appearance_Fairy(1, 0, "enemy_fairy1");
	enemy_renders["enemy_fairy3"] = new Enemy_Appearance_Fairy(2, 1, "enemy_fairy1");
	enemy_renders["enemy_fairy10"] = new Enemy_Appearance_Fairy(0, 0, "enemy_fairy2");
	enemy_renders["enemy_kedama"] = new Enemy_Appearance_Kedama();
	enemy_renders["enemy_boss1"] = new Enemy_Appearance_Boss1("letty");

	effect_renders["magic_flash"] = new Appearance_Effect_Magic_Flash();
	effect_renders["enemy_shot100"] = new Appearance_Effect_Enemy_Shot1(100);
	effect_renders["enemy_shot200"] = new Appearance_Effect_Enemy_Shot1(200);
	effect_renders["enemy_shot500"] = new Appearance_Effect_Enemy_Shot1(500);
	effect_renders["enemy_shot_other100"] = new Appearance_Effect_Enemy_Shot2(100);
	effect_renders["enemy_shot_other200"] = new Appearance_Effect_Enemy_Shot2(200);
	effect_renders["enemy_shot_other500"] = new Appearance_Effect_Enemy_Shot2(500);
	effect_renders["score_float"] = new Appearance_Effect_Score_Float	(gc, resources);
	effect_renders["player_bullet_hit1"] = new Appearance_Effect_Player_Bullet_Hit1();
	effect_renders["player_bullet_hit2"] = new Appearance_Effect_Player_Bullet_Hit2(1.0f);
	effect_renders["player_bullet_hit3"] = new Appearance_Effect_Player_Bullet_Hit3();
	effect_renders["player_bullet_hit4"] = new Appearance_Effect_Player_Bullet_Hit2(1.1f);
	effect_renders["player_bullet_hit5"] = new Appearance_Effect_Player_Bullet_Hit2(1.2f);
	effect_renders["player_bullet_hit6"] = new Appearance_Effect_Player_Bullet_Hit2(1.3f);
	effect_renders["player_bullet_hit7"] = new Appearance_Effect_Player_Bullet_Hit2(1.5f);
	effect_renders["enemy_bullet_hit1"] = new Appearance_Effect_Enemy_Bullet_Hit1();
	effect_renders["cancelled_bullet"] = new Appearance_Effect_Cancelled_Bullet();
	effect_renders["particle_happa"] = new Appearance_Effect_Happa_Particle();
	effect_renders["particle_snow"] = new Appearance_Effect_Snow_Particle();
	effect_renders["particle_small"] = new Appearance_Effect_Small_Particle();
	effect_renders["graze_particle"] = new Appearance_Effect_Graze_Particle();
	effect_renders["letty_cloud"] = new Appearance_Effect_Letty_Cloud(2000);
	effect_renders["boss_name"] = new Appearance_Effect_Boss_Name();
	effect_renders["spellcard_result"] = new Appearance_Effect_Spellcard_Result(gc, resources);
	effect_renders["spellcard_name"] = new Appearance_Effect_Spellcard_Name(gc, resources);
}

Appearance* RenderManager::GetBulletRender(CL_String name)
{
	return bullet_renders[name.c_str()];
}

Enemy_Appearance* RenderManager::GetEnemyRender(CL_String name)
{
	return enemy_renders[name.c_str()];
}

Effect_Appearance* RenderManager::GetEffectRender(CL_String name)
{
	return effect_renders[name.c_str()];
}

// ==============================================================
// ===                                      Рендеры пуль
// ==============================================================

// Круглые пули
Appearance_Simple::Appearance_Simple(CL_String sprite_name, int frame_offset)
{
	sprite = sprite_container.GetSprite(sprite_name);
	index = 0;
	offset = frame_offset;
	sprite->set_frame(0);
}

void Appearance_Simple::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	if (p_bullet->appearance_index != index)
	{
		index = p_bullet->appearance_index % 16;
	}
	sprite->set_frame(offset + index);
	if (!p_bullet->owner)
		sprite->set_alpha(player.bullet_alpha);
	else
		sprite->set_alpha(1);
	sprite->set_scale(1, 1);
	sprite->set_alignment(origin_center);
	sprite->set_angle(CL_Angle(0, cl_radians));
	sprite->draw(gc, p_bullet->position.x,p_bullet->position.y);
}

// Круглые пули масштабированные
Appearance_Simple_Zoomed::Appearance_Simple_Zoomed(CL_String sprite_name, int frame_offset, float z)
{
	sprite = sprite_container.GetSprite(sprite_name);
	index = 0;
	offset = frame_offset;
	sprite->set_frame(0);
	zoom = z;
}

void Appearance_Simple_Zoomed::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	if (p_bullet->appearance_index != index)
	{
		index = p_bullet->appearance_index % 16;
	}
	sprite->set_frame(offset + index);
	if (!p_bullet->owner)
		sprite->set_alpha(player.bullet_alpha);
	else
		sprite->set_alpha(1);
	sprite->set_scale(zoom, zoom);
	sprite->set_alignment(origin_center);
	sprite->set_angle(CL_Angle(0, cl_radians));
	sprite->draw(gc, p_bullet->position.x,p_bullet->position.y);
}

// Продолговатые пули
Appearance_Bullet_Pike::Appearance_Bullet_Pike(CL_String sprite_name, int frame_offset)
{
	sprite = sprite_container.GetSprite(sprite_name);
	index = 0;
	offset = frame_offset;
	sprite->set_frame(0);
}

void Appearance_Bullet_Pike::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	if (p_bullet->appearance_index != index)
	{
		index = p_bullet->appearance_index % 16;
	}
	sprite->set_frame(offset + index);
	if (!p_bullet->owner)
		sprite->set_alpha(player.bullet_alpha);
	else
		sprite->set_alpha(1);
	//CL_Angle a(p_bullet->direction.angle(CL_Vec2<float>(1,0)) - CL_Angle(90, cl_degrees));
	//if (p_bullet->direction.y < 0)
	//	a = CL_Angle(360, cl_degrees) - a;
	//else
	//	a = CL_Angle(180, cl_degrees) + a;
	//sprite->set_angle(a);
	sprite->set_angle(p_bullet->orientation + CL_Angle(90, cl_degrees));
	sprite->set_alignment(origin_center);
	sprite->set_scale(1, 1);
	sprite->draw(gc, p_bullet->position.x,p_bullet->position.y);
}

// Пули игрока
Appearance_Player_Bullet1::Appearance_Player_Bullet1()
{
}

void Appearance_Player_Bullet1::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	player.player_sprite.set_frame(24);
	player.player_sprite.set_alpha(player.bullet_alpha);
	CL_Angle a(p_bullet->direction.angle(CL_Vec2<float>(1,0)) - CL_Angle(90, cl_degrees));
	if (p_bullet->direction.y < 0)
		a = CL_Angle(360 - 90, cl_degrees) - a;
	else
		a = CL_Angle(180 - 90, cl_degrees) + a;
	player.player_sprite.set_angle(a);
	player.player_sprite.set_alignment(origin_center);
	player.player_sprite.draw(gc, p_bullet->position.x,p_bullet->position.y);
}

Appearance_Player_Bullet_Focus1::Appearance_Player_Bullet_Focus1(float f)
{
	f_scale = f;
}

void Appearance_Player_Bullet_Focus1::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	player.player_sprite.set_frame(28);
	player.player_sprite.set_alpha(player.bullet_alpha);
	CL_Angle a(p_bullet->direction.angle(CL_Vec2<float>(1,0)) - CL_Angle(90, cl_degrees));
	if (p_bullet->direction.y < 0)
		a = CL_Angle(360 - 90, cl_degrees) - a;
	else
		a = CL_Angle(180 - 90, cl_degrees) + a;
	player.player_sprite.set_angle(a);
	player.player_sprite.set_alignment(origin_center);
	player.player_sprite.set_scale(1.0f, f_scale);
	player.player_sprite.draw(gc, p_bullet->position.x,p_bullet->position.y);
	player.player_sprite.set_scale(1.0f, 1.0f);
}

Appearance_Player_Bullet2::Appearance_Player_Bullet2()
{
}

void Appearance_Player_Bullet2::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	player.player_sprite.set_frame(32);
	player.player_sprite.set_alpha(player.bullet_alpha);
	CL_Angle a(p_bullet->direction.angle(CL_Vec2<float>(1,0)) - CL_Angle(90, cl_degrees));
	if (p_bullet->direction.y < 0)
		a = CL_Angle(360 - 90, cl_degrees) - a;
	else
		a = CL_Angle(180 - 90, cl_degrees) + a;
	player.player_sprite.set_angle(a);
	player.player_sprite.set_alignment(origin_center);
	player.player_sprite.draw(gc, p_bullet->position.x,p_bullet->position.y);
}

// ===========   Лазоры   ===========================

// Обычный прямой лазор
Appearance_Lazor::Appearance_Lazor()
{
	sprite = sprite_container.GetSprite("bullets");
	sprite_tip = sprite_container.GetSprite("magic_flash");
	index = 0;
	sprite->set_frame(0);
}

void Appearance_Lazor::Render(CL_GraphicContext &gc, Bullet *p_bullet)
{
	if (p_bullet->appearance_index != index)
	{
		index = p_bullet->appearance_index % 16;
	}
	sprite->set_frame(index);
	sprite->set_alpha(1);
	sprite->set_scale(1, 50);
	sprite->set_alignment(origin_center);
	sprite->set_angle(p_bullet->orientation + CL_Angle(90, cl_degrees));
	sprite->draw(gc, p_bullet->start_position.x,p_bullet->start_position.y);

	sprite_tip->set_frame(int(p_bullet->time_lived /20) % 4);
	sprite_tip->set_scale(2,2);
	sprite_tip->set_alpha(1);
	sprite_tip->set_alignment(origin_center);
	sprite_tip->draw(gc, p_bullet->prev_position.x,p_bullet->prev_position.y);
}

// ==============================================================
// ===                                      Рендеры врагов
// ==============================================================

// Обычная феечка
// Может быть с вращающимся кругом под ней
Enemy_Appearance_Fairy::Enemy_Appearance_Fairy(int ring, int lights, CL_String f_sprite)
{
	sprite = sprite_container.GetSprite(f_sprite);
	sprite_splash = sprite_container.GetSprite("fairy_splash");
	sprite_ring = sprite_container.GetSprite("fairy_circle");
	sprite_big_ring = sprite_container.GetSprite("fairy_big_circle");
	sprite_lights = sprite_container.GetSprite("magic_flash");
	show_ring = ring;
	show_lights = lights;
}

//CL_Size Enemy_Appearance_Fairy::GetSpriteSize()
//{
//	return sprite->get_size();
//}

void Enemy_Appearance_Fairy::Render(CL_GraphicContext &gc, Enemy *p_enemy)
{
	if (p_enemy->time_from_last_frame > 100) // скорость анимации крылышек
	{
		p_enemy->time_from_last_frame -=100;
		p_enemy->animation_frame = (p_enemy->animation_frame + 1) % 4;
	}
	if (show_ring)
	{
		// Отобразить крутящееся магическоекольцо под феечкой
		if (show_ring > 1)
		{
			// большое кольцо
			float scl = 1.5f;
			sprite_big_ring->set_scale(scl, scl);
			sprite_big_ring->set_angle(CL_Angle(-p_enemy->time_lived/12.0f, cl_degrees));
			sprite_big_ring->set_alignment(origin_center);
			sprite_big_ring->draw(gc, p_enemy->position.x, p_enemy->position.y);
		}
		else
		{
			// малое кольцо
			sprite_ring->set_alpha(0.6f);
			float scl = 1.5f + 0.3f * sin(CL_Angle(p_enemy->time_lived / 4.0f, cl_degrees).to_radians());
			sprite_ring->set_scale(scl, scl);
			sprite_ring->set_angle(CL_Angle(p_enemy->time_lived/2.0f, cl_degrees));
			sprite_ring->set_frame(p_enemy->version);
			sprite_ring->set_alignment(origin_center);
			sprite_ring->draw(gc, p_enemy->position.x, p_enemy->position.y);
		}
	}
	if (show_lights)
	{
		// Крутящиеся свечения
		sprite_lights->set_alpha(0.6f);
		for (int a = 0; a < 12; a++)
		{
			CL_Angle an((float)(a*30) + p_enemy->time_lived / 11.0f, cl_degrees);
			sprite_lights->set_alpha(1.0f);
			sprite_lights->set_scale(1.0f, 1.0f);
			sprite_lights->set_frame(p_enemy->version * 4 + ((p_enemy->animation_frame + a) % 4));
			sprite_lights->set_alignment(origin_center);
			sprite_lights->draw(gc, p_enemy->position.x + 56.0f * cos(an.to_radians()), p_enemy->position.y  + 56.0f * sin(an.to_radians()));
		}
	}
	if (abs(sin(p_enemy->orientation.to_radians())) > 0.9)
	{
		// вертикальная проекция
		sprite->set_alpha(1.0f);
		sprite->set_angle_yaw(CL_Angle(0, cl_degrees));
		sprite->set_color(CL_Colorf(1.0f, 1.0f, 1.0f));
		sprite->set_frame(p_enemy->version * 12 + p_enemy->animation_frame);
		sprite->set_alignment(origin_center);
		sprite->draw(gc, p_enemy->position.x, p_enemy->position.y);
	}
	else if (abs(sin(p_enemy->orientation.to_radians())) < 0.5)
	{
		// горизонтальная проекция
		sprite->set_alpha(1.0f);
		sprite->set_angle_yaw(cos(p_enemy->orientation.to_radians()) > 0 ? CL_Angle(0, cl_degrees) : CL_Angle(180, cl_degrees));
		sprite->set_color(CL_Colorf(1.0f, 1.0f, 1.0f));
		sprite->set_frame(p_enemy->version * 12 + 8 + p_enemy->animation_frame);
		sprite->set_alignment(origin_center);
		sprite->draw(gc, p_enemy->position.x, p_enemy->position.y);
	}
	else
	{
		// постепенный разворот
		sprite->set_alpha(1.0f);
		sprite->set_angle_yaw(cos(p_enemy->orientation.to_radians()) > 0 ? CL_Angle(0, cl_degrees) : CL_Angle(180, cl_degrees));
		sprite->set_color(CL_Colorf(1.0f, 1.0f, 1.0f));
		sprite->set_frame(p_enemy->version * 12 + 8 - int(abs(sin(p_enemy->orientation.to_radians())) * 10.0f - 5.0f));
		sprite->set_alignment(origin_center);
		sprite->draw(gc, p_enemy->position.x, p_enemy->position.y);
	}
}

int Enemy_Appearance_Fairy::RenderDead(CL_GraphicContext &gc, Enemy *p_enemy)
{
	if (p_enemy->time_lived > 400)
		return 0;
	// пульнём частицами
	if (p_enemy->time_lived < 200)
	{
		if (((int)(p_enemy->time_lived / 50)) > p_enemy->score)
		{
			p_enemy->score ++;
			CL_Angle a((float)(rand() % 360), cl_degrees);
			Effect new_effect;
			new_effect.position = p_enemy->position;
			new_effect.direction = CL_Vec2<float>(cos(a.to_radians()), sin(a.to_radians()));
			new_effect.speed = 0.5f + (float)(rand() % 100) / 500;
			new_effect.appearance = renders.GetEffectRender("particle_happa");
			new_effect.behaviour = patterns.GetEffectBehaviour("effect_flyoff");
			new_effect.param_float = 0.5f + (float)(rand() % 100) / 200;
			effects.Create(new_effect);
		}
	}
	sprite_splash->set_frame(p_enemy->version);
	sprite_splash->set_alpha((500.0f - p_enemy->time_lived) / 500.0f);
	float scale1 = (600.0f + p_enemy->time_lived*2.2f) / 600.0f;
	float scale2 = (400.0f + p_enemy->time_lived*3) / 400.0f;
	float scale3 = (1000.0f - p_enemy->time_lived) / 2000;
	sprite_splash->set_alignment(origin_center);
	sprite_splash->set_scale(scale1, scale1);
	sprite_splash->draw(gc, p_enemy->position.x, p_enemy->position.y);
	sprite_splash->set_scale(scale2, scale3);
	sprite_splash->draw(gc, p_enemy->position.x, p_enemy->position.y);
	sprite_splash->set_scale(scale3, scale2);
	sprite_splash->draw(gc, p_enemy->position.x, p_enemy->position.y);
	if (p_enemy->time_lived < 100)
	{
		// вспышка самой феи
		sprite->set_frame(p_enemy->version * 12);
		sprite->set_color(CL_Colorf(1.5f, 1.5f, 1.5f));
		sprite->set_alpha((100 - p_enemy->time_lived) / 100);
		sprite->set_alignment(origin_center);
		sprite->draw(gc, p_enemy->position.x, p_enemy->position.y);
	}
	return 1;
}

// Кедама
Enemy_Appearance_Kedama::Enemy_Appearance_Kedama()
{
	sprite = sprite_container.GetSprite("kedama");
	sprite_splash = sprite_container.GetSprite("fairy_splash");
}

void Enemy_Appearance_Kedama::Render(CL_GraphicContext &gc, Enemy *p_enemy)
{
	sprite->update();
	// горизонтальная проекция
	sprite->set_alpha(1.0f);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_enemy->position.x, p_enemy->position.y);
}

int Enemy_Appearance_Kedama::RenderDead(CL_GraphicContext &gc, Enemy *p_enemy)
{
	if (p_enemy->time_lived > 400)
		return 0;
	// пульнём частицами
	if (p_enemy->time_lived < 200)
	{
		if (((int)(p_enemy->time_lived / 50)) > p_enemy->score)
		{
			p_enemy->score ++;
			CL_Angle a((float)(rand() % 360), cl_degrees);
			Effect new_effect;
			new_effect.position = p_enemy->position;
			new_effect.direction = CL_Vec2<float>(cos(a.to_radians()), sin(a.to_radians()));
			new_effect.speed = 0.5f + (float)(rand() % 100) / 500;
			new_effect.appearance = renders.GetEffectRender("particle_happa");
			new_effect.behaviour = patterns.GetEffectBehaviour("effect_flyoff");
			new_effect.param_float = 0.5f + (float)(rand() % 100) / 200;
			effects.Create(new_effect);
		}
	}
	sprite_splash->set_frame(p_enemy->version);
	sprite_splash->set_alpha((500.0f - p_enemy->time_lived) / 500.0f);
	float scale1 = (600.0f + p_enemy->time_lived*2.2f) / 600.0f;
	float scale2 = (400.0f + p_enemy->time_lived*3) / 400.0f;
	float scale3 = (1000.0f - p_enemy->time_lived) / 2000;
	sprite_splash->set_alignment(origin_center);
	sprite_splash->set_scale(scale1, scale1);
	sprite_splash->draw(gc, p_enemy->position.x, p_enemy->position.y);
	sprite_splash->set_scale(scale2, scale3);
	sprite_splash->draw(gc, p_enemy->position.x, p_enemy->position.y);
	sprite_splash->set_scale(scale3, scale2);
	sprite_splash->draw(gc, p_enemy->position.x, p_enemy->position.y);
	return 1;
}

// ============ Боссы ==============================

// Boss1 - Летти
Enemy_Appearance_Boss1::Enemy_Appearance_Boss1(CL_String name)
{
	sprite = sprite_container.GetSprite("enemy_boss_" + name);
	sprite_splash = sprite_container.GetSprite("fairy_splash");
}

void Enemy_Appearance_Boss1::Render(CL_GraphicContext &gc, Enemy *p_enemy)
{
	EnemyBoss *b_enemy;
	if (p_enemy->is_boss)
		b_enemy = static_cast<EnemyBoss*> (p_enemy);
	else
		return; // wut
	sprite->set_angle_yaw(CL_Angle(0, cl_degrees));
	if (b_enemy->moving)
	{
		// В движении
		if (abs(b_enemy->move.x / b_enemy->move.y) < 0.04f)
		{
			// вертикальное движение
			sprite->set_frame((int)(b_enemy->time_lived /100) % 4); // скорость анимации 100мс
		}
		else
		{
			// Горизонтальное движение
			if (b_enemy->position.distance(b_enemy->position2) < 5.0f)
				sprite->set_frame(4);
			else if (b_enemy->position.distance(b_enemy->position2) < 15.0f)
				sprite->set_frame(5);
			else if (b_enemy->position.distance(b_enemy->position2) < 25.0f)
				sprite->set_frame(6);
			else if (b_enemy->move_time < 300)
				sprite->set_frame(4);
			else if (b_enemy->move_time < 500)
				sprite->set_frame(5);
			else if (b_enemy->move_time < 700)
				sprite->set_frame(6);
			else
				sprite->set_frame(7);
			if (b_enemy->move.x < 0)
				sprite->set_angle_yaw(CL_Angle(180, cl_degrees));
		}
		b_enemy->ukanderu = 0;
	}
	else if (b_enemy->acting)
	{
		// Выполняет действие
		if (b_enemy->act_time < 200)
			sprite->set_frame(8);
		else if (b_enemy->act_time < 400)
			sprite->set_frame(9);
		else
			sprite->set_frame(10 + ((int)(b_enemy->time_lived /100) % 2));
		b_enemy->ukanderu = 0;
	}
	else
	{
		// Стоит на месте
		sprite->set_frame((int)(b_enemy->time_lived /100) % 4); // скорость анимации 100мс
	}
	sprite->set_alpha(1.0f);
	sprite->set_alignment(origin_center);
	if (b_enemy->ukanderu)
	{
		// парим вверх-вниз
		sprite->draw(gc, p_enemy->position.x, p_enemy->position.y + sin(b_enemy->ukanderu / 250.0f) * 3.0f);
	}
	else
	{
		// движемся
		sprite->draw(gc, p_enemy->position.x, p_enemy->position.y);
	}
}

int Enemy_Appearance_Boss1::RenderDead(CL_GraphicContext &gc, Enemy *p_enemy)
{
	if (p_enemy->time_lived > 2000)
		return 0;
	// поток частиц
	p_enemy->score ++;
	CL_Angle a(150.0f + (float)(rand() % 270), cl_degrees);
	Effect new_effect;
	new_effect.position = p_enemy->position + CL_Vec2f((float)(rand() % 100) / 10.0f - 5.0f, (float)(rand() % 100) / 10.0f - 5.0f);
	new_effect.direction = CL_Vec2<float>(cos(a.to_radians()), sin(a.to_radians()));
	new_effect.speed = 0.2f + (float)(rand() % 100) / 500;
	new_effect.appearance = renders.GetEffectRender("particle_snow");
	new_effect.behaviour = patterns.GetEffectBehaviour("effect_grav");
	new_effect.param_float = 0.8f + (float)(rand() % 100) / 200;
	new_effect.eff_color = CL_Colorf(0.8f + (float)(rand() % 100)/500.0f, 0.8f + (float)(rand() % 100)/500.0f, 0.8f + (float)(rand() % 100)/500.0f, 1.0f);
	effects.Create(new_effect);
	new_effect.position = p_enemy->position + CL_Vec2f((float)(rand() % 100) / 10.0f - 5.0f, (float)(rand() % 100) / 10.0f - 5.0f);
	new_effect.eff_color = CL_Colorf(0.8f + (float)(rand() % 100)/500.0f, 0.8f + (float)(rand() % 100)/500.0f, 0.8f + (float)(rand() % 100)/500.0f, 1.0f);
	new_effect.speed = 0.2f + (float)(rand() % 100) / 500;
	a = CL_Angle(150.0f + (float)(rand() % 270), cl_degrees);
	new_effect.direction = CL_Vec2<float>(cos(a.to_radians()), sin(a.to_radians()));
	new_effect.param_float = 0.8f + (float)(rand() % 100) / 200;
	effects.Create(new_effect);
	new_effect.position = p_enemy->position + CL_Vec2f((float)(rand() % 100) / 10.0f - 5.0f, (float)(rand() % 100) / 10.0f - 5.0f);
	new_effect.eff_color = CL_Colorf(0.8f + (float)(rand() % 100)/500.0f, 0.8f + (float)(rand() % 100)/500.0f, 0.8f + (float)(rand() % 100)/500.0f, 1.0f);
	new_effect.speed = 0.2f + (float)(rand() % 100) / 500;
	a = CL_Angle(150.0f + (float)(rand() % 270), cl_degrees);
	new_effect.direction = CL_Vec2<float>(cos(a.to_radians()), sin(a.to_radians()));
	new_effect.param_float = 0.8f + (float)(rand() % 100) / 200;
	effects.Create(new_effect);
	return 1;
}

void Enemy_Appearance_Boss1::RenderBack(CL_GraphicContext &gc, Enemy *p_enemy, float time)
{
	EnemyBoss *b_enemy;
	if (p_enemy->is_boss)
		b_enemy = static_cast<EnemyBoss*> (p_enemy);
	else
		return; // wut
	// Просчитать круги
	for (int i = 0; i < b_enemy->rnd_rings; i++)
	{
		b_enemy->rnd_ring_position[i] += b_enemy->rnd_ring_speed[i] * time;
		if (b_enemy->rnd_ring_status[i] == 0)
		{
			// инициализация кольца
			float wspeed = 0.3f; // скорость расширения
			b_enemy->rnd_ring_radius[i] += wspeed * time;
			if (b_enemy->rnd_ring_radius[i] > b_enemy->rnd_ring_temp[i])
			{
				b_enemy->rnd_ring_radius[i] = b_enemy->rnd_ring_temp[i];
				b_enemy->rnd_ring_status[i] = 1;
				b_enemy->rnd_ring_alpha[i] = 1.0f;
			}
			b_enemy->rnd_ring_alpha[i] = b_enemy->rnd_ring_radius[i] / b_enemy->rnd_ring_temp[i];
		}
		else if (b_enemy->rnd_ring_status[i] == 2)
		{
			// Передислокация кольца
			float wspeed = 0.3f; // скорость перемещения
			if (b_enemy->rnd_ring_radius[i] > b_enemy->rnd_ring_temp[i])
			{
				// Кольцо сжимается
				b_enemy->rnd_ring_radius[i] -= wspeed * time;
				if (b_enemy->rnd_ring_radius[i] <= b_enemy->rnd_ring_temp[i])
				{
					// Достигли нужного радиуса
					b_enemy->rnd_ring_radius[i] = b_enemy->rnd_ring_temp[i];
					b_enemy->rnd_ring_status[i] = 1;
				}
			}
			else
			{
				// Кольцо расширяется
				b_enemy->rnd_ring_radius[i] += wspeed * time;
				if (b_enemy->rnd_ring_radius[i] >= b_enemy->rnd_ring_temp[i])
				{
					// Достигли нужного радиуса
					b_enemy->rnd_ring_radius[i] = b_enemy->rnd_ring_temp[i];
					b_enemy->rnd_ring_status[i] = 1;
				}
			}
		}
		else if (b_enemy->rnd_ring_status[i] == 3)
		{
			// Кольцо на выкидывание
			float wspeed = 0.5f; // скорость расширения
			b_enemy->rnd_ring_radius[i] += wspeed * time;
			if (b_enemy->rnd_ring_radius[i] > b_enemy->rnd_ring_temp[i])
			{
				// Выкидываем кольцо из массива
				b_enemy->rnd_ring_status[i] = 4;
			}
		}
	}
	int r_count = 0;
	while (r_count <  b_enemy->rnd_rings)
	{
		if (b_enemy->rnd_ring_status[r_count] == 4)
		{
			int r_move = r_count;
			while (r_move <  (b_enemy->rnd_rings - 1))
			{
				b_enemy->rnd_ring_status[r_move] = b_enemy->rnd_ring_status[r_move + 1];
				b_enemy->rnd_ring_status[r_move] = b_enemy->rnd_ring_status[r_move + 1];
				b_enemy->rnd_ring_index[r_move] = b_enemy->rnd_ring_index[r_move + 1];
				b_enemy->rnd_ring_radius[r_move] = b_enemy->rnd_ring_radius[r_move + 1];
				b_enemy->rnd_ring_temp[r_move] = b_enemy->rnd_ring_temp[r_move + 1];
				b_enemy->rnd_ring_width[r_move] = b_enemy->rnd_ring_width[r_move + 1];
				b_enemy->rnd_ring_speed[r_move] = b_enemy->rnd_ring_speed[r_move + 1];
				b_enemy->rnd_ring_alpha[r_move] = b_enemy->rnd_ring_alpha[r_move + 1];
				b_enemy->rnd_ring_position[r_move] = b_enemy->rnd_ring_position[r_move + 1];
				r_move++;
			}
			b_enemy->rnd_rings--;
		}
		else
			r_count++;
	}
}

void Enemy_Appearance_Boss1::RenderFront(CL_GraphicContext &gc, Enemy *p_enemy, float time)
{
	EnemyBoss *b_enemy;
	if (p_enemy->is_boss)
		b_enemy = static_cast<EnemyBoss*> (p_enemy);
	else
		return; // wut
}


// ==============================================================
// ===                                      Рендеры эффектов
// ==============================================================


Appearance_Effect_Magic_Flash::Appearance_Effect_Magic_Flash()
{
	sprite = sprite_container.GetSprite("magic_flash");
	index = 0;
	sprite->set_frame(0);
}

int Appearance_Effect_Magic_Flash::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->time_lived > 200)
		return 0;
	if (p_effect->appearance_index != index)
	{
		index = p_effect->appearance_index % 4;
	}
	sprite->set_frame(index * 4 + (int)((200 - p_effect->time_lived)/50));
	sprite->set_alpha((400 - p_effect->time_lived) / 400);
	sprite->set_scale(1.0f, 1.0f);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x,p_effect->position.y);
	return 1;
}

// Выстрел врага
// За время работы собирается с большого полупрозрачного облака выстрела в малое яркое и исчезает
Appearance_Effect_Enemy_Shot1::Appearance_Effect_Enemy_Shot1(float dur)
{
	sprite = sprite_container.GetSprite("bullets");
	index = 0;
	duration = dur;
}

int Appearance_Effect_Enemy_Shot1::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится duration мс
	if (p_effect->time_lived > duration)
		return 0;
	if (p_effect->appearance_index != index)
	{
		index = p_effect->appearance_index % 16;
	}
	sprite->set_frame(224 + index);
	sprite->set_alpha((duration + p_effect->time_lived) / (duration * 2.0f));
	float scale = 1.5f - (p_effect->time_lived / duration);
	//cl_log_event("Debug", "Render effect  scale %1", scale);
	sprite->set_scale(scale, scale);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x,p_effect->position.y);
	sprite->set_scale(1.0f, 1.0f);
	sprite->set_alpha(1.0f);
	return 1;
}

// Обратный Shot1 выстрел
// Начинается как малое яркое облако, постепенно рассеиваясь на нет в большое
Appearance_Effect_Enemy_Shot2::Appearance_Effect_Enemy_Shot2(float dur)
{
	sprite = sprite_container.GetSprite("bullets");
	index = 0;
	duration = dur;
}

int Appearance_Effect_Enemy_Shot2::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится duration мс
	if (p_effect->time_lived > duration)
		return 0;
	if (p_effect->appearance_index != index)
	{
		index = p_effect->appearance_index % 16;
	}
	sprite->set_frame(224 + index);
	sprite->set_alpha((duration - p_effect->time_lived) / duration);
	float scale = 1.0f + (p_effect->time_lived / duration);
	//cl_log_event("Debug", "Render effect  scale %1", scale);
	sprite->set_scale(scale, scale);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x,p_effect->position.y);
	sprite->set_scale(1.0f, 1.0f);
	sprite->set_alpha(1.0f);
	return 1;
}

// Всплывающие полученные очки
Appearance_Effect_Score_Float::Appearance_Effect_Score_Float(CL_GraphicContext &gc, CL_ResourceManager &resources)
{
	bonus_score_font = new CL_Font_Sprite(gc, "font_b_score", &resources);
	font_sprite = sprite_container.GetSprite("font_bonus_score");
}

int Appearance_Effect_Score_Float::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	int t = p_effect->param_int;
	float divx = 0;
	t /=10;
	while(t > 1)
	{
		divx +=3.0f;
		t /=10;
	}
	float divy = (p_effect->time_lived / p_effect->speed) * 30;
	float alpha = 0.8f;
	if (p_effect->time_lived < (p_effect->speed/3))
		alpha = 2.4f * p_effect->time_lived / p_effect->speed;
	font_sprite->set_alpha(alpha);
	CL_Colorf c;
	if (p_effect->appearance_index == 1)
		c = CL_Colorf::yellow;
	else if (p_effect->appearance_index == 2)
		c = CL_Colorf::gray80;
	else
		c = CL_Colorf::white;
	c.a = alpha;
	font_sprite->set_color(c);
	t = p_effect->param_int;
	while(t >= 1)
	{
		int cur_n = t % 10;
		font_sprite->set_frame(cur_n);
		font_sprite->set_alignment(origin_center);
		font_sprite->draw(gc, p_effect->position.x + divx, p_effect->position.y - divy);
		divx -= font_sprite->get_width();
		t /=10;
	}
	
	//int t = p_effect->param_int;
	//float divx = -3;
	//t /=10;
	//while(t > 1)
	//{
	//	divx -=3;
	//	t /=10;
	//}
	//float divy = (p_effect->time_lived / p_effect->speed) * 30;
	//float alpha = 0.8f;
	//if (p_effect->time_lived < (p_effect->speed/3))
	//	alpha = 2.4f * p_effect->time_lived / p_effect->speed;
	//bonus_score_font->set_alpha(alpha);
	//CL_Colorf c;
	//if (p_effect->appearance_index == 1)
	//	c = CL_Colorf::yellow;
	//else if (p_effect->appearance_index == 2)
	//	c = CL_Colorf::gray80;
	//else
	//	c = CL_Colorf::white;
	//c.a = alpha;
	//bonus_score_font->draw_text(gc, p_effect->position.x + divx, p_effect->position.y - divy, 1.0f, 1.0f, CL_StringHelp::int_to_text(p_effect->param_int), c);
	return 1;
}

Appearance_Effect_Player_Bullet_Hit1::Appearance_Effect_Player_Bullet_Hit1()
{
}

int Appearance_Effect_Player_Bullet_Hit1::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится 200 мс
	if (p_effect->time_lived > 200)
		return 0;

	if (p_effect->time_lived < 70)
		player.player_sprite.set_frame(25);
	else if (p_effect->time_lived < 140)
		player.player_sprite.set_frame(26);
	else
		player.player_sprite.set_frame(27);
	
	player.player_sprite.set_alpha(((300.0f - p_effect->time_lived) / 400) * player.bullet_alpha);

	CL_Angle a(p_effect->direction.angle(CL_Vec2<float>(1,0)) - CL_Angle(180, cl_degrees));
	if (p_effect->direction.y < 0)
		a = CL_Angle(360, cl_degrees) - a;
	player.player_sprite.set_angle(a);
	player.player_sprite.set_alignment(origin_center);
	player.player_sprite.draw(gc, p_effect->position.x,p_effect->position.y);
	return 1;
}

// Пули в фокусе
Appearance_Effect_Player_Bullet_Hit2::Appearance_Effect_Player_Bullet_Hit2(float f)
{
	f_scale = f;
}

int Appearance_Effect_Player_Bullet_Hit2::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится 200 мс
	if (p_effect->time_lived > 200)
		return 0;

	if (p_effect->time_lived < 50)
		player.player_sprite.set_frame(29);
	else if (p_effect->time_lived < 100)
		player.player_sprite.set_frame(30);
	else
		player.player_sprite.set_frame(31);
	
	player.player_sprite.set_alpha(((300.0f - p_effect->time_lived) / 400) * player.bullet_alpha);
	player.player_sprite.set_angle(CL_Angle(-90, cl_degrees));
	player.player_sprite.set_alignment(origin_center);
	player.player_sprite.set_scale(1.0f, f_scale);
	player.player_sprite.draw(gc, p_effect->position.x,p_effect->position.y);
	player.player_sprite.set_scale(1.0f, 1.0f);
	return 1;
}

Appearance_Effect_Player_Bullet_Hit3::Appearance_Effect_Player_Bullet_Hit3()
{
}

int Appearance_Effect_Player_Bullet_Hit3::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится 200 мс
	if (p_effect->time_lived > 200)
		return 0;

	if (p_effect->time_lived < 70)
		player.player_sprite.set_frame(33);
	else if (p_effect->time_lived < 140)
		player.player_sprite.set_frame(34);
	else
		player.player_sprite.set_frame(35);
	
	player.player_sprite.set_alpha(((300.0f - p_effect->time_lived) / 400) * player.bullet_alpha);

	CL_Angle a(p_effect->direction.angle(CL_Vec2<float>(1,0)) - CL_Angle(180, cl_degrees));
	if (p_effect->direction.y < 0)
		a = CL_Angle(360, cl_degrees) - a;
	player.player_sprite.set_angle(a);
	player.player_sprite.set_alignment(origin_center);
	player.player_sprite.draw(gc, p_effect->position.x,p_effect->position.y);
	return 1;
}

Appearance_Effect_Enemy_Bullet_Hit1::Appearance_Effect_Enemy_Bullet_Hit1()
{
	sprite = sprite_container.GetSprite("bullets");
	index = 0;
}

int Appearance_Effect_Enemy_Bullet_Hit1::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится 200 мс
	if (p_effect->time_lived > 200)
		return 0;

	index = p_effect->appearance_index % 16;
	if (p_effect->time_lived < 50)
		sprite->set_frame(240 + index);
	else
		sprite->set_frame(256 + index);
	float sc = (150.0f + p_effect->time_lived) / 150.0f;
	
	sprite->set_alpha((300.0f - p_effect->time_lived) / 350.0f);
	sprite->set_scale(sc, sc);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x,p_effect->position.y);
	sprite->set_scale(1.0f, 1.0f);
	sprite->set_alpha(1.0f);
	return 1;
}

Appearance_Effect_Cancelled_Bullet::Appearance_Effect_Cancelled_Bullet()
{
	sprite1 = sprite_container.GetSprite("bullets");
	sprite2 = sprite_container.GetSprite("magic_flash");
	index = 0;
}

int Appearance_Effect_Cancelled_Bullet::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится 300 мс
	if (p_effect->time_lived > 300)
		return 0;
	index = p_effect->appearance_index % 16;
	sprite1->set_frame(224 + index);
	sprite2->set_frame((int)(p_effect->time_lived / 20) % 4);
	float scale1 = (320.0f - p_effect->time_lived) / 300;
	float scale2 = 1.5f + (p_effect->time_lived / 200);
	sprite1->set_scale(scale1, scale1);
	sprite1->set_alpha((1000.0f - p_effect->time_lived) / 1000.0f);
	sprite1->set_alignment(origin_center);
	sprite1->draw(gc, p_effect->position.x,p_effect->position.y);
	sprite1->set_scale(1.0f, 1.0f);
	sprite1->set_alpha(1.0f);
	sprite2->set_scale(scale2, scale2);
	sprite2->set_alignment(origin_center);
	sprite2->set_alpha((300.0f - p_effect->time_lived) / 400.0f);
	sprite2->draw(gc, p_effect->position.x,p_effect->position.y);
	return 1;
}

Appearance_Effect_Happa_Particle::Appearance_Effect_Happa_Particle()
{
	sprite = sprite_container.GetSprite("effects");
}

int Appearance_Effect_Happa_Particle::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->time_lived > 500)
		return 0;
	sprite->set_frame(0);
	sprite->set_color(CL_Colorf::white);
	sprite->set_angle(CL_Angle(p_effect->time_lived, cl_degrees));
	sprite->set_scale(p_effect->param_float, p_effect->param_float);
	sprite->set_alpha((500 - p_effect->time_lived) / 500);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x, p_effect->position.y);
	return 1;
}

Appearance_Effect_Snow_Particle::Appearance_Effect_Snow_Particle()
{
	sprite = sprite_container.GetSprite("effects");
}

int Appearance_Effect_Snow_Particle::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->time_lived > 800)
		return 0;
	sprite->set_frame(1);
	sprite->set_color(p_effect->eff_color);
	//sprite->set_angle(CL_Angle(p_effect->time_lived, cl_degrees));
	sprite->set_scale(p_effect->param_float, p_effect->param_float);
	sprite->set_alpha((800 - p_effect->time_lived) / 500);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x, p_effect->position.y);
	return 1;
}

Appearance_Effect_Small_Particle::Appearance_Effect_Small_Particle()
{
	sprite = sprite_container.GetSprite("magic_flash");
}

int Appearance_Effect_Small_Particle::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->time_lived > 200)
		return 0;
	sprite->set_frame(((int)p_effect->time_lived % 50) + p_effect->appearance_index * 4);
	sprite->set_scale(p_effect->param_float, p_effect->param_float);
	sprite->set_alpha((500 - p_effect->time_lived) / 500);
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x, p_effect->position.y);
	return 1;
}

Appearance_Effect_Graze_Particle::Appearance_Effect_Graze_Particle()
{
	sprite = sprite_container.GetSprite("bullets");
}

int Appearance_Effect_Graze_Particle::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->time_lived > (float)p_effect->param_int)
		return 0;
	sprite->set_frame(64 + p_effect->appearance_index);
	sprite->set_scale(p_effect->param_float, p_effect->param_float);
	if (p_effect->time_lived > (float)p_effect->param_int / 2.0f)
		sprite->set_alpha((((float)p_effect->param_int / 2.0f) - (p_effect->time_lived - ((float)p_effect->param_int/ 2.0f))) / ((float)p_effect->param_int / 2.0f));
	else
		sprite->set_alpha(0.8f);
	sprite->set_angle(p_effect->orientation + CL_Angle(90.0f, cl_degrees));
	sprite->set_alignment(origin_center);
	sprite->draw(gc, p_effect->position.x ,p_effect->position.y);
	sprite->set_scale(1.0f, 1.0f);
	sprite->set_alpha(1.0f);
	return 1;
}

Appearance_Effect_Letty_Cloud::Appearance_Effect_Letty_Cloud(float dur)
{
	sprite = sprite_container.GetSprite("smoke");
	duration = dur;
}

int Appearance_Effect_Letty_Cloud::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	// Длится duration
	if (p_effect->time_lived > duration)
		return 0;

	float a;
	int f;
	if (p_effect->time_lived < duration / 2.0f)
	{
		a = 1.0f;
		f = (int)(p_effect->time_lived * 8.0f / duration);
	}
	else
	{
		a = (duration - p_effect->time_lived) / (duration * 0.9f);
		f = 3;
	}
	float sc = 3.0f + 1.5f * p_effect->time_lived / duration;
	
	sprite->set_frame(f);
	//sprite->set_alpha(a);
	sprite->set_alpha(1.0f);
	sprite->set_scale(sc, sc);
	sprite->set_alignment(origin_center);
	sprite->set_angle(p_effect->orientation);
	sprite->set_frame(f);
	sprite->draw(gc, p_effect->position.x,p_effect->position.y);
	sprite->set_scale(1.0f, 1.0f);
	sprite->set_alpha(1.0f);
	sprite->set_angle(CL_Angle(0, cl_radians));
	return 1;
}

Appearance_Effect_Boss_Name::Appearance_Effect_Boss_Name()
{
	sprite = sprite_container.GetSprite("boss_names");
}

int Appearance_Effect_Boss_Name::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->time_lived > 700)
		p_effect->param_float = 0;
	else
		p_effect->param_float = p_effect->time_lived/5.8f - 120.0f;
	sprite->set_frame(p_effect->param_int);
	sprite->set_alignment(origin_top_left);
	sprite->draw(gc, p_effect->position.x + p_effect->param_float, p_effect->position.y);
	return global_state.game_boss_battle;
}

// Результат спеллкарты с количеством полученных очков
Appearance_Effect_Spellcard_Result::Appearance_Effect_Spellcard_Result(CL_GraphicContext &gc, CL_ResourceManager &resources)
{
	_score_font = new CL_Font_Sprite(gc, "font_spell_score", &resources);
	font_sprite = sprite_container.GetSprite("font_spellcard");
}

int Appearance_Effect_Spellcard_Result::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	float a;
	if (p_effect->time_lived > 1000)
		a = (4000.0f - p_effect->time_lived) / 3000.0f;
	else
		a = 1.0f;

	if (p_effect->time_lived > 4000)
		return 0;
	else
	{
		if (p_effect->param_int)
		{
			// Spellcard bonus
			font_sprite->set_frame(1);
			CL_String sptext(CL_StringHelp::int_to_text(p_effect->param_int));
			int text_size = font_sprite->get_width();
			int text_height = font_sprite->get_height();
			int num_size = _score_font->get_text_size(gc, sptext).width;
			int overall_size = text_size + num_size + 16;
			font_sprite->set_frame(1);
			font_sprite->set_color(CL_Colorf::white);
			font_sprite->set_alpha(a);
			CL_Colorf n_col(1.0f, 1.0f, 1.0f, a);
			font_sprite->set_alignment(origin_bottom_left);
			font_sprite->draw(gc, p_effect->position.x - (overall_size / 2), p_effect->position.y + (text_height/2));
			_score_font->draw_text(gc, p_effect->position.x + (overall_size / 2) - num_size, p_effect->position.y + (text_height/2) - 6, 1.0f, 1.0f, sptext, n_col);
		}
		else
		{
			// Spellcard failed
			font_sprite->set_frame(0);
			font_sprite->set_alignment(origin_center);
			font_sprite->set_color(CL_Colorf::coral);
			font_sprite->set_alpha(a);
			font_sprite->draw(gc, p_effect->position.x + 10.0f, p_effect->position.y);
		}
		return 1;
	}
}

// Название спеллкарты
Appearance_Effect_Spellcard_Name::Appearance_Effect_Spellcard_Name(CL_GraphicContext &gc, CL_ResourceManager &resources)
{
	_sprite = sprite_container.GetSprite("spellcard_names");
}

int Appearance_Effect_Spellcard_Name::Render(CL_GraphicContext &gc, Effect *p_effect)
{
	if (p_effect->active)
	{
		int _frame = p_effect->param_int;
		if (!global_state.lang)
			_frame +=2;
		float a;
		if (p_effect->time_lived > 300)
			a = 1.0f;
		else
			a = p_effect->time_lived / 300.0f;
		_sprite->set_frame(_frame);
		_sprite->set_alpha(a);
		_sprite->set_alignment(origin_top_right);

		float _size = 0.5f;
		p_effect->position.x = 410;
		p_effect->position.y = 38;
		if (p_effect->time_lived < 600)
		{
			_size = 1.0f;
			float _cursize = (float)_sprite->get_width() * _size;
			float _xdif = (372 - _cursize) / 2;
			p_effect->position.y = 200;
			p_effect->position.x = 410 - _xdif;
		}
		else if (p_effect->time_lived < 1200)
		{
			_size = 1.0f - (float)(p_effect->time_lived - 600)/1200.0f;
			float _cursize = (float)_sprite->get_width() * _size;
			float _xdif = (372 - _cursize) / 2;
			p_effect->position.y = 200 - (float)(p_effect->time_lived - 600)*162.0f/600.0f;
			p_effect->position.x = 410 - _xdif * (float)(1200 - p_effect->time_lived)/600.0f;
		}
		// Spellcard name
		_sprite->set_scale(_size, _size);
		_sprite->draw(gc, p_effect->position.x, p_effect->position.y);
	}
	return 1;
}
